import { SubjectComponent } from "../../../../core/subject";

const { executeInEditMode, ccclass, property } = cc._decorator;

@ccclass
// @executeInEditMode
export default class Stick extends SubjectComponent {
    @property
    staticPad = false;
    @property(cc.Node)
    pad: cc.Node = null;

    @property(cc.Node)
    handle: cc.Node = null;

    @property
    waitTime = 1.0;

    @property
    fadeTime = 0.5;

    showing = false;
    touching = false;

    moving = false;
    showTime = 0;

    protected onLoad(): void {
        this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.node.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
    }

    onTouchStart(evt: cc.Event.EventTouch) {
        let loc = evt.getLocation();
        this.touching = true;
        if (this.showing) {
            this.pad.opacity = 255;
        }
        else {
            if (!this.staticPad) {
                let np = this.node.convertToNodeSpaceAR(loc);
                let areaBox = this.node.getBoundingBoxToWorld();
                np = this.posInArea(np, this.pad.getContentSize(), areaBox);
                this.pad.setPosition(np);
            }
        }

        cc.Tween.stopAllByTarget(this.pad);
        this.pad.opacity = 255;
        this.showing = true;
    }
    posInArea(np: cc.Vec2, size: cc.Size, box: cc.Rect) {
        if (np.len() > this.node.width / 2) {
            return np.normalize().mul(this.node.width / 2);
        }
        return np;
    }
    onTouchMove(evt: cc.Event.EventTouch) {
        let loc = evt.getLocation();
        if (this.showing) {
            let np = this.pad.convertToNodeSpaceAR(loc);
            let areaBox = this.pad.getBoundingBoxToWorld();
            np = this.posInArea(np, this.handle.getContentSize(), areaBox);
            this.handle.setPosition(np);
        }
    }
    onTouchEnd(evt: cc.Event.EventTouch) {
        this.touching = false;
        this.showTime = this.waitTime;
    }

    protected update(dt: number): void {
        if (!this.touching && this.showing && this.showTime > 0) {
            if (this.showTime -= dt) {
                if (this.showTime < 0) {
                    this.showTime = 0;
                    cc.Tween.stopAllByTarget(this.pad);
                    cc.tween(this.pad).to(this.fadeTime, { opacity: 0 }).call(() => {
                        this.showing = false;
                    }).start();
                }
            }
        }

        if (!this.touching) {
            this.handle.setPosition(this.handle.position.mul(0.95));
        }

        if (this.showing) {
            let pcV2 = cc.v2(
                this.handle.x / (this.pad.width / 2),
                this.handle.y / (this.pad.height / 2)
            );
            if (pcV2.len() > 0.3) {
                this.emit("move", pcV2);
                this.moving = true;
            }
            else {
                if (this.moving) {
                    this.emit("stop");
                    this.moving = false;
                }
            }
        }
        else {
            if (this.moving) {
                this.emit("stop");
                this.moving = false;
            }
        }
    }
};